package com.java.Collection;

import java.util.*;
import java.util.function.Consumer;

/**
 * 单列集合Collection遍历：其子类List(ArrayList、LinkedList、Vector)和Set(HashSet(LinkedHashSet)、TreeSet)均适用
 */
public class CollectionTraverse {
    // Iterator遍历：每一个迭代器对象只能遍历一次，指针不会复位
    public static <E> void collectionIterator(Collection<E> collection) {
        Iterator<E> iterator = collection.iterator();
        while (iterator.hasNext()) { // hasNext：判断下一个指针位置是否有元素
            E e = iterator.next(); // next：指针下移并获取下移后指针位置元素，若无元素则抛出异常NoSuchElementException
            System.out.print(e + " ");

            // 迭代过程中只能使用迭代器的remove移除元素而不能利用集合的remove，否则抛出异常ConcurrentModificationException
            // 若使用集合API改变集合，但迭代器无法同步改变，导致迭代器内集合与实际集合不一致，进而抛出并发修改异常
            if ("TYT".equals(e)) {
                // collection.remove(str);
                iterator.remove();
            }

            // 遍历时直接改变对象地址值则原集合内对象不变，改变对象内属性值时则原集合内对象属性改变
        }
        System.out.println();
    }

    // 增强for循环遍历：底层就是迭代器，迭代器的注意事项同样适用于增强for循环，只有单列集合Collection和数组才可使用
    public static <E> void collectionPowerFor(Collection<E> collection) {
        for (E e : collection) {
            System.out.print(e + " ");

            // 遍历时直接改变对象地址值则原集合内对象不变，改变对象内属性值时则原集合内对象属性改变
        }
        System.out.println();
    }

    // forEach遍历：底层就是增强for循环
    public static <E> void collectionForEach(Collection<E> collection) {
        collection.forEach(new Consumer<E>() {
            @Override
            public void accept(E e) {
                System.out.print(e + " ");

                // 遍历时直接改变对象地址值则原集合内对象不变，改变对象内属性值时则原集合内对象属性改变
            }
        });
        System.out.println();
    }

    // lambda简化forEach遍历
    public static <E> void collectionForEachLambda(Collection<E> collection) {
        collection.forEach(e -> {
            System.out.print(e + " ");

            // 遍历时直接改变对象地址值则原集合内对象不变，改变对象内属性值时则原集合内对象属性改变
        });
        System.out.println();
    }

    public static void main(String[] args) {
        Collection<String> arrayList = new ArrayList<>(Arrays.asList("MJQ", "DCX", "SYX", "LYW", "ZZY", "YHX", "HJL", "TYT"));
        Collection<String> linkedList = new LinkedList<>(Arrays.asList("MJQ", "DCX", "SYX", "LYW", "ZZY", "YHX", "HJL", "TYT"));
        Collection<String> hashSet = new HashSet<>(Arrays.asList("MJQ", "DCX", "SYX", "LYW", "ZZY", "YHX", "HJL", "TYT"));
        Collection<String> linkedHashSet = new LinkedHashSet<>(Arrays.asList("MJQ", "DCX", "SYX", "LYW", "ZZY", "YHX", "HJL", "TYT"));
        Collection<String> treeSet = new TreeSet<>(Arrays.asList("MJQ", "DCX", "SYX", "LYW", "ZZY", "YHX", "HJL", "TYT"));

        // Iterator遍历
        collectionIterator(arrayList); // MJQ DCX SYX LYW ZZY YHX HJL TYT
        collectionIterator(linkedList); // MJQ DCX SYX LYW ZZY YHX HJL TYT
        collectionIterator(hashSet); // SYX MJQ DCX ZZY YHX LYW HJL TYT
        collectionIterator(linkedHashSet); // MJQ DCX SYX LYW ZZY YHX HJL TYT
        collectionIterator(treeSet); // DCX HJL LYW MJQ SYX TYT YHX ZZY

        // 增强for循环遍历
        collectionPowerFor(arrayList); // MJQ DCX SYX LYW ZZY YHX HJL
        collectionPowerFor(linkedList); // MJQ DCX SYX LYW ZZY YHX HJL
        collectionPowerFor(hashSet); // SYX MJQ DCX ZZY YHX LYW HJL
        collectionPowerFor(linkedHashSet); // MJQ DCX SYX LYW ZZY YHX HJL TYT
        collectionPowerFor(treeSet); // DCX HJL LYW MJQ SYX YHX ZZY

        // forEach遍历
        collectionForEach(arrayList); // MJQ DCX SYX LYW ZZY YHX HJL
        collectionForEach(linkedList); // MJQ DCX SYX LYW ZZY YHX HJL
        collectionForEach(hashSet); // SYX MJQ DCX ZZY YHX LYW HJL
        collectionForEach(linkedHashSet); // MJQ DCX SYX LYW ZZY YHX HJL TYT
        collectionForEach(treeSet); // DCX HJL LYW MJQ SYX YHX ZZY

        // lambda简化forEach遍历
        collectionForEachLambda(arrayList); // MJQ DCX SYX LYW ZZY YHX HJL
        collectionForEachLambda(linkedList); // MJQ DCX SYX LYW ZZY YHX HJL
        collectionForEachLambda(hashSet); // SYX MJQ DCX ZZY YHX LYW HJL
        collectionForEachLambda(linkedHashSet); // MJQ DCX SYX LYW ZZY YHX HJL TYT
        collectionForEachLambda(treeSet); // DCX HJL LYW MJQ SYX YHX ZZY

        System.out.println(arrayList); // [MJQ, DCX, SYX, LYW, ZZY, YHX, HJL]
        System.out.println(linkedList); // [MJQ, DCX, SYX, LYW, ZZY, YHX, HJL]
        System.out.println(hashSet); // [SYX, MJQ, DCX, ZZY, YHX, LYW, HJL]
        System.out.println(linkedHashSet); // [MJQ, DCX, SYX, LYW, ZZY, YHX, HJL]
        System.out.println(treeSet); // [DCX, HJL, LYW, MJQ, SYX, YHX, ZZY]
    }
}
